﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PortConfigViewModel.cs" company="R.V.Kasner">
//   Copyright © 2011 R.V.Kasner
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Owen.Terminal.ViewModel
{
    using System.Collections.Generic;
    using System.IO.Ports;

    using Microsoft.Practices.Prism.Events;

    using Owen.Communication.Serial;
    using Owen.Communication.Service;
    using Owen.Terminal.Events;
    using Owen.Terminal.Properties;
    using Owen.Terminal.View;

    public sealed class PortConfigViewModel : ViewModelBase<IPortConfigView>, IPortConfigViewModel
    {
        private bool isEditable;

        private PortSettings portSettings;

        public PortConfigViewModel(IPortConfigView view, IEventAggregator eventAggregator)
            : base(view)
        {
            this.portSettings.PortName = Settings.Default.PortName;
            this.portSettings.Parity = Settings.Default.Parity;
            this.portSettings.StopBits = Settings.Default.StopBits;
            this.portSettings.Handshake = Settings.Default.Handshake;
            this.portSettings.BaudRate = Settings.Default.BaudRate;
            this.portSettings.DataBits = (DataBits)Settings.Default.DataBits;
            this.portSettings.ReadTimeout = Settings.Default.ReadTimeout;

            this.isEditable = true;

            eventAggregator.GetEvent<ConnectChangeEvent>().Subscribe(this.OnConnectChange);
        }

        public int BaudRate
        {
            get
            {
                return this.portSettings.BaudRate;
            }

            set
            {
                if (this.portSettings.BaudRate == value) return;

                this.portSettings.BaudRate = value;
                Settings.Default.BaudRate = value;
                this.RaisePropertyChanged("BaudRate");
            }
        }

        public DataBits DataBits
        {
            get
            {
                return this.portSettings.DataBits;
            }

            set
            {
                if (this.portSettings.DataBits == value) return;

                this.portSettings.DataBits = value;
                Settings.Default.DataBits = (int)value;
                this.RaisePropertyChanged("DataBits");
            }
        }

        public Handshake Handshake
        {
            get
            {
                return this.portSettings.Handshake;
            }

            set
            {
                if (this.portSettings.Handshake == value) return;

                this.portSettings.Handshake = value;
                Settings.Default.Handshake = value;
                this.RaisePropertyChanged("Handshake");
            }
        }

        public bool IsEditable
        {
            get
            {
                return this.isEditable;
            }

            private set
            {
                this.isEditable = value;
                this.RaisePropertyChanged("IsEditable");
            }
        }

        public Parity Parity
        {
            get
            {
                return this.portSettings.Parity;
            }

            set
            {
                if (this.portSettings.Parity == value) return;

                this.portSettings.Parity = value;
                Settings.Default.Parity = value;
                this.RaisePropertyChanged("Parity");
            }
        }

        public string PortName
        {
            get
            {
                return this.portSettings.PortName;
            }

            set
            {
                if (this.portSettings.PortName == value) return;

                this.portSettings.PortName = value;
                Settings.Default.PortName = value;
                this.RaisePropertyChanged("PortName");
            }
        }

        public IList<string> PortNames
        {
            get
            {
                return SerialPort.GetPortNames();
            }
        }

        public int ReadTimeout
        {
            get
            {
                return this.portSettings.ReadTimeout;
            }

            set
            {
                if (this.portSettings.ReadTimeout == value) return;

                this.portSettings.ReadTimeout = value;
                Settings.Default.ReadTimeout = value;
                this.RaisePropertyChanged("ReadTimeout");
            }
        }

        public StopBits StopBits
        {
            get
            {
                return this.portSettings.StopBits;
            }

            set
            {
                if (this.portSettings.StopBits == value) return;

                this.portSettings.StopBits = value;
                Settings.Default.StopBits = value;
                this.RaisePropertyChanged("StopBits");
            }
        }

        public PortConfigValidValues ValidValues
        {
            get
            {
                return PortConfigValidValues.Default;
            }
        }

        public PortSettings GetPortSettings()
        {
            return this.portSettings.Clone();
        }

        private void OnConnectChange(SignallerStates obj)
        {
            this.IsEditable = (obj & SignallerStates.Open) == SignallerStates.Open ? false : true;
        }
    }
}